package com.tencent.iov.cowin.befsale.clue.service.cus.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.software.boot.common.entity.Page;
import com.software.boot.common.entity.Response;
import com.software.boot.common.exception.BusinessException;
import com.software.boot.common.exception.NEError;
import com.software.boot.common.model.dao.PageRequest;
import com.software.boot.common.model.dao.PageResponse;
import com.software.boot.common.util.BeanUtil;
import com.software.boot.common.util.DateUtil;
import com.software.boot.common.util.EmptyUtils;
import com.software.boot.common.util.ValidateUtils;
import com.software.common.config.SearchLocalHeader;
import com.software.common.enums.DeleteEnum;
import com.software.common.enums.SCRMRequestHeaderEnum;
import com.tencent.iov.cowin.befsale.clue.controller.clue.assembler.ClueCustomerCollectAssembler;
import com.tencent.iov.cowin.befsale.clue.controller.clue.vo.request.ChannelActivityRequest;
import com.tencent.iov.cowin.befsale.clue.controller.clue.vo.request.QueryClueCustomerCollectAllRequest;
import com.tencent.iov.cowin.befsale.clue.controller.clue.vo.request.SectorDealerRequest;
import com.tencent.iov.cowin.befsale.clue.controller.clue.vo.response.ClueCustomerCollectResponse;
import com.tencent.iov.cowin.befsale.clue.controller.clue.vo.response.ClueExportResponse;
import com.tencent.iov.cowin.befsale.clue.controller.clue.vo.response.ClueIntentionVehicleResponse;
import com.tencent.iov.cowin.befsale.clue.controller.cus.assembler.DealerCustomerAssembler;
import com.tencent.iov.cowin.befsale.clue.controller.cus.vo.request.QueryCustomerFollowRecordRequest;
import com.tencent.iov.cowin.befsale.clue.controller.cus.vo.request.QueryCustomerRequest;
import com.tencent.iov.cowin.befsale.clue.controller.cus.vo.request.UpdateClueEmpRequest;
import com.tencent.iov.cowin.befsale.clue.controller.cus.vo.request.UpdateCustomerRequest;
import com.tencent.iov.cowin.befsale.clue.controller.cus.vo.response.ClueDictionariesResponse;
import com.tencent.iov.cowin.befsale.clue.controller.cus.vo.response.CustomerFollowRecordResponse;
import com.tencent.iov.cowin.befsale.clue.controller.cus.vo.response.CustomerResponse;
import com.tencent.iov.cowin.befsale.clue.dao.http.mdquery.MdQueryClient;
import com.tencent.iov.cowin.befsale.clue.dao.http.mdquery.request.QueryCustomerBaseRequest;
import com.tencent.iov.cowin.befsale.clue.dao.http.mdquery.request.QueryDealerRequest;
import com.tencent.iov.cowin.befsale.clue.dao.http.mdquery.response.CustomerBaseResponse;
import com.tencent.iov.cowin.befsale.clue.dao.http.mdquery.response.DealerResponse;
import com.tencent.iov.cowin.befsale.clue.dao.http.personal.PersonalClient;
import com.tencent.iov.cowin.befsale.clue.dao.http.personal.request.ClueCustomerTransferRequest;
import com.tencent.iov.cowin.befsale.clue.dao.http.tenant.request.QueryDictionariesRequest;
import com.tencent.iov.cowin.befsale.clue.dao.http.tenant.response.DictionariesResponse;
import com.tencent.iov.cowin.befsale.clue.dao.http.tencent.ITencentSaasClient;
import com.tencent.iov.cowin.befsale.clue.domain.clue.po.Clue;
import com.tencent.iov.cowin.befsale.clue.domain.clue.po.ClueCustomerCollect;
import com.tencent.iov.cowin.befsale.clue.domain.clue.po.ClueIntentionVehicle;
import com.tencent.iov.cowin.befsale.clue.domain.cus.po.OemCustomer;
import com.tencent.iov.cowin.befsale.clue.domain.cus.vo.ClueDictionaryMapped;
import com.tencent.iov.cowin.befsale.clue.domain.cus.vo.ClueDictionaryMappedCollect;
import com.tencent.iov.cowin.befsale.clue.repository.tenant.TenantManager;
import com.tencent.iov.cowin.befsale.clue.service.clue.ClueCustomerCollectService;
import com.tencent.iov.cowin.befsale.clue.service.clue.ClueIntentionVehicleService;
import com.tencent.iov.cowin.befsale.clue.service.clue.ClueService;
import com.tencent.iov.cowin.befsale.clue.service.clue.ClueTodoRelService;
import com.tencent.iov.cowin.befsale.clue.service.cus.CustomerFollowRecordService;
import com.tencent.iov.cowin.befsale.clue.service.cus.CustomerService;
import com.tencent.iov.cowin.befsale.clue.service.cus.DealerCustomerService;
import com.tencent.iov.cowin.befsale.clue.service.cus.OemCustomerService;
import com.tencent.iov.cowin.befsale.clue.value.enums.*;
import com.tencent.iov.cowin.befsale.clue.value.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Author xiamu
 * @Date 2022/1/14 14:55
 * @Version 1.0
 **/
@Service
@Slf4j
public class CustomerServiceImpl implements CustomerService {

    private final static int clueExportMergeSize = 19;

    @Autowired
    private DealerCustomerService dealerCustomerService;
    @Autowired
    private OemCustomerService oemCustomerService;
    @Autowired
    private TenantManager tenantManager;
    @Autowired
    private ClueDictionaryMappedCollect dictionaryMappedCollect;
    @Autowired
    private ClueCustomerCollectService clueCustomerCollectService;
    @Autowired
    private CustomerFollowRecordService customerFollowRecordService;
    @Autowired
    private ITencentSaasClient iTencentSaasClient;
    @Autowired
    private ClueIntentionVehicleService clueIntentionVehicleService;
    @Autowired
    private MdQueryClient mdQueryClient;
    @Autowired
    private ClueService clueService;
    @Autowired
    private ClueTodoRelService clueTodoRelService;
    @Autowired
    private PersonalClient personalClient;
    @Value("${clue-todo.template.msgTodoFollowClue.id}")
    private Long followTodoId;

    final String dirName = "clue";

    @Override
    public CustomerResponse getDetailByIdAndDealerId(Long id, String dealerId) {
        if (CustomerUtil.isDealer() || CustomerUtil.isDealer(dealerId)) {
            return dealerCustomerService.getDetailById(id);
        }
        //总部
        return oemCustomerService.getDetailById(id);
    }

    @Override
    public CustomerResponse getOemCustomerDetailByIdAndDealerId(Long id, String dealerId) {
        //总部
        if (!CustomerUtil.isDealer(dealerId)) {
            return oemCustomerService.getDetailById(id);
        }
        CustomerResponse dealerResponse = dealerCustomerService.getDetailById(id);
        if (EmptyUtils.isEmpty(dealerResponse) || EmptyUtils.isEmpty(dealerResponse.getOemCusId())
                || dealerResponse.getOemCusId() <= 0) {
            return null;
        }
        return oemCustomerService.getDetailById(dealerResponse.getOemCusId());
    }

    @Override
    public List<CustomerResponse> getListByParam(QueryCustomerRequest request) {
        if (CustomerUtil.isDealer()) {
            return dealerCustomerService.getListByParam(request);
        }
        return oemCustomerService.getListByParam(request);
    }


    @Override
    public Map<Long, CustomerResponse> getCustomerMapByCusType(QueryCustomerRequest request) {
        ValidateUtils.checkObjNull(request.getCusType(), "客户类型不可以为null");
        List<CustomerResponse> customerResponses = null;
        if (CustomerTypeEnum.isDealer(request.getCusType())) {
            customerResponses = dealerCustomerService.getListByParam(request);
        }
        if (CustomerTypeEnum.isOem(request.getCusType())) {
            customerResponses = oemCustomerService.getListByParam(request);
        }
        if (EmptyUtils.isEmpty(customerResponses)) {
            return null;
        }
        return customerResponses.stream().collect(Collectors.toMap(CustomerResponse::getId, dealer -> dealer, (oldValue, newValue) -> newValue));
    }

    @Override
    public CustomerResponse getOneByParam(QueryCustomerRequest request) {
        if (CustomerUtil.isDealer()) {
            return dealerCustomerService.getOneByParam(request);
        }
        OemCustomer oemCustomer = BeanUtil.copy(request, OemCustomer.class);
        return oemCustomerService.getOneByParam(oemCustomer);
    }


    @Override
    public List<ClueDictionariesResponse> getClueCustomerDictionaries() {
        if (EmptyUtils.isEmpty(dictionaryMappedCollect.getCustomerBaseTypes())) {
            throw new BusinessException(NEError.INVALID_PARAMETER, "客户标签字典信息不存在");
        }
        List<String> types = dictionaryMappedCollect.getCustomerBaseTypes().stream().map(ClueDictionaryMapped::getType).collect(Collectors.toList());

        //查询获取字典信息
        QueryDictionariesRequest request = new QueryDictionariesRequest();
        request.setTypes(types);
        List<DictionariesResponse> dictionariesResponses = tenantManager.getDicListByParam(request);
        if (EmptyUtils.isEmpty(dictionariesResponses)) {
            throw new BusinessException(NEError.BUSINESS_ERROR, "未查询到字典信息");
        }
        //整理数据
        Map<String, List<DictionariesResponse>> dictionaryMap = dictionariesResponses.stream().collect(Collectors.groupingBy(DictionariesResponse::getType));
        if (EmptyUtils.isEmpty(dictionaryMap)) {
            throw new BusinessException(NEError.BUSINESS_ERROR, "处理字典信息失败");
        }
        List<ClueDictionariesResponse> clueDictionariesResponses = Lists.newArrayList();
        dictionaryMappedCollect.getCustomerBaseTypes().forEach(clueDictionaryMapped -> {
            if (!dictionaryMap.containsKey(clueDictionaryMapped.getType()) || EmptyUtils.isEmpty(dictionaryMap.get(clueDictionaryMapped.getType()))) {
                return;
            }
            ClueDictionariesResponse clueDictionariesResponse = BeanUtil.copy(clueDictionaryMapped, ClueDictionariesResponse.class);
            clueDictionariesResponse.setDictionaries(dictionaryMap.get(clueDictionaryMapped.getType()));
            clueDictionariesResponses.add(clueDictionariesResponse);
        });
        return clueDictionariesResponses;
    }

    @Override
    public String getClueCustomerTagStr(CustomerResponse customerResponse) {
        List<ClueDictionaryMapped> customerBaseTypes = dictionaryMappedCollect.getCustomerBaseTypes();
        if (EmptyUtils.isEmpty(customerBaseTypes)) {
            return "";
        }
        List<String> types = customerBaseTypes.stream().map(ClueDictionaryMapped::getType).collect(Collectors.toList());

        //查询获取字典信息
        QueryDictionariesRequest request = new QueryDictionariesRequest();
        request.setTypes(types);
        List<DictionariesResponse> dicList = tenantManager.getDicListByParam(request);
        if (EmptyUtils.isEmpty(dicList)) {
            throw new BusinessException(NEError.BUSINESS_ERROR, "未查询到字典信息");
        }
        return DealerCustomerAssembler.getCustomerTags(dicList, customerResponse);
    }

    @Override
    public Boolean updateCustomerInfo(UpdateCustomerRequest request) {
        //更新customer_base_id
        if(StringUtils.isNotBlank(request.getExternalUserid())){
            QueryCustomerBaseRequest baseRequest = new QueryCustomerBaseRequest();
            baseRequest.setDeleted(DeletedEnum.EXIST.getCode());
            baseRequest.setExternalUserid(request.getExternalUserid());
            log.info("调用主数据查询客户信息，外部联系人参数：【{}】",JSON.toJSONString(baseRequest));
            Response<List<CustomerBaseResponse>> response = mdQueryClient.getListByParam(baseRequest);
            log.info("调用主数据拆线呢客户信息，返回：【{}】",JSON.toJSONString(response));
            if(Objects.nonNull(response) && response.getCode() == 0 && CollectionUtils.isNotEmpty(response.getData())){
                Long id = response.getData().get(0).getId();
                request.setCustomerBaseId(id);
            }
        }
        if (CustomerUtil.isDealer()) {
            return dealerCustomerService.updateDealerCustomer(request);
        }
        return oemCustomerService.updateOemCustomer(request);
    }

    @Override
    public Map<Long, CustomerResponse> distributeCustomers(UpdateClueEmpRequest request, List<Clue> clues) {
        if (CustomerUtil.isDealer()) {
            List<Long> cusIds = clues.stream().map(Clue::getCusId).collect(Collectors.toList());
            UpdateCustomerRequest customerRequest = UpdateCustomerRequest.builder()
                    .ids(cusIds)
                    .followEmpId(request.getFollowEmpId())
                    .followEmpName(request.getFollowEmpName())
                    .deleted(DeleteEnum.INIT.getFlag())
                    .build();
            QueryCustomerRequest queryCustomerRequest = new QueryCustomerRequest();
            queryCustomerRequest.setIds(cusIds);
            queryCustomerRequest.setDeleted(DeleteEnum.INIT.getFlag());
            List<CustomerResponse> customerResponses = dealerCustomerService.getListByParam(queryCustomerRequest);
            if (EmptyUtils.isEmpty(customerResponses) || customerResponses.size() < cusIds.size()) {
                throw new BusinessException(NEError.BUSINESS_ERROR, "经销商客户信息不存在");
            }
            Map<Long, CustomerResponse> customerMap = customerResponses.stream().collect(Collectors.toMap(CustomerResponse::getId, Function.identity(), (o, v) -> v));

            //查询需要在职继承的数据
            List<ClueCustomerTransferRequest> cctrList = new ArrayList<ClueCustomerTransferRequest>();


            QueryCustomerRequest requestQuery = new QueryCustomerRequest();
            requestQuery.setIds(cusIds);
            requestQuery.setDeleted(DeleteEnum.INIT.getFlag());
            List<CustomerResponse> responseList =  dealerCustomerService.getListByParam(requestQuery);
            responseList.stream().filter(c -> EmptyUtils.isNotEmpty(c.getCustomerBaseId())).forEach(cr -> {
                ClueCustomerTransferRequest cctr = new ClueCustomerTransferRequest();
                cctr.setOldEmpId(cr.getFollowEmpId());
                cctr.setTargetEmpId(request.getFollowEmpId());
                ClueCustomerTransferRequest.TransferCustomerRequest ct = new ClueCustomerTransferRequest.TransferCustomerRequest();
                ct.setCustomerBaseId(cr.getCustomerBaseId().toString());
                List<ClueCustomerTransferRequest.TransferCustomerRequest> list = new ArrayList<>();
                list.add(ct);
                cctr.setCustomerList(list);
                cctrList.add(cctr);
            });

            log.info("调用在职继承接口，参数：【{}】", JSON.toJSONString(cctrList));
            personalClient.incumbencyTransfer(cctrList);
            //查询需要在职继承的数据END

            //更新经销商客户信息
            int customerResult = dealerCustomerService.update(customerRequest);
            if (customerResult <= 0) {
                throw new BusinessException(NEError.BUSINESS_ERROR, "更新经销商客户信息失败");
            }
            for (Clue clue : clues) {
                clueTodoRelService.updateClueTodoTask(MsgTodoEnum.FOLLOW_CLUE.getCode(), clue.getId(), String.valueOf(request.getFollowEmpId()));

                //对接代办
                request.setClueId(clue.getId());
                processFollowTodoParam(request, customerResponses);
            }
            return customerMap;
        }
        throw new BusinessException(NEError.BUSINESS_ERROR, "总部暂不支持分配顾问功能");
    }

    private void processFollowTodoParam(UpdateClueEmpRequest request, List<CustomerResponse> customerResponses) {
        Date date = DateUtil.addHours(new Date(), 24);
        String dateStr = DateUtil.toDateString(date, "yyyy-MM-dd HH:mm");

        List<Long> empIds = new ArrayList<>();

        empIds.add(request.getFollowEmpId());
        for (CustomerResponse cus : customerResponses) {
            Map<String, Object> todoMap = new HashMap<>();
            String content = "产品介绍";
            String name = cus.getName();
            String phone = cus.getPhone();
            clueService.makeFollowTodoTask(date, empIds, content, name, phone, request.getClueId(),null,null,cus.getExternalUserid());
        }
    }

    @Override
    public CustomerResponse distributeCustomer(UpdateClueEmpRequest request, Clue clue) {
        if (CustomerUtil.isDealer() || CustomerUtil.isDealer(clue.getDealerId())) {
            CustomerResponse customerResponse = dealerCustomerService.getDetailById(clue.getCusId());
            if (EmptyUtils.isEmpty(customerResponse) || DeleteEnum.DETELED.getFlag().equals(customerResponse.getDeleted())) {
                throw new BusinessException(NEError.BUSINESS_ERROR, "经销商客户信息不存在");
            }
            if (EmptyUtils.isEmpty(request.getFollowEmpId())) {
                return customerResponse;
            }

            UpdateCustomerRequest customerRequest = UpdateCustomerRequest.builder()
                    .id(clue.getCusId())
                    .followEmpId(request.getFollowEmpId())
                    .followEmpName(request.getFollowEmpName())
                    .deleted(DeleteEnum.INIT.getFlag())
                    .build();

            //更新经销商客户信息
            int customerResult = dealerCustomerService.update(customerRequest);
            if (customerResult <= 0) {
                throw new BusinessException(NEError.BUSINESS_ERROR, "更新经销商客户信息失败");
            }
            return customerResponse;
        }

        //总部客户分配客户
        CustomerResponse customerResponse = oemCustomerService.getDetailById(clue.getCusId());
        if (EmptyUtils.isEmpty(customerResponse) || DeleteEnum.DETELED.getFlag().equals(customerResponse.getDeleted())) {
            throw new BusinessException(NEError.BUSINESS_ERROR, "经销商客户信息不存在");
        }
        if (EmptyUtils.isEmpty(request.getFollowEmpId())) {
            return customerResponse;
        }
        UpdateCustomerRequest customerRequest = UpdateCustomerRequest.builder()
                .id(clue.getCusId())
                .followEmpId(request.getFollowEmpId())
                .followEmpName(request.getFollowEmpName())
                .deleted(DeleteEnum.INIT.getFlag())
                .build();

        //更新总部商客户信息
        int customerResult = oemCustomerService.update(customerRequest);
        if (customerResult <= 0) {
            throw new BusinessException(NEError.BUSINESS_ERROR, "更新总部客户信息失败");
        }
        return customerResponse;
    }

    @Override
    public String exportClueCollectAndFollowList(PageRequest<QueryClueCustomerCollectAllRequest> request) {
        //获取所有线索信息
        List<ClueCustomerCollectResponse> clueList = getClueCustomerCollectResponses(request);
        if (EmptyUtils.isEmpty(clueList)) {
            return "暂无线索信息";
        }

        //获取填充跟进历史的导出数据
        List<ClueExportResponse> responseList = getClueCustomerCollectExportResponses(clueList);

        File dir = new File(dirName);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        String pathStr = String.format("%s/线索列表_%d.xlsx", dirName, DateUtil.getMillis(new Date()));
        try {
            //写入Excel文件
            Map<String, List<RowRangeUtil>> strategyMap = addMerStrategy(responseList);
            EasyExcel.write(pathStr, ClueExportResponse.class)
                    //合并单元格的策略
                    .registerWriteHandler(new ManagerExportStrategyUtil(strategyMap))
                    .registerWriteHandler(new CustomCellWriteHandler())
                    .sheet("线索列表")
                    .doWrite(responseList);

            File file = new File(pathStr);

            //转化file文件
            MultipartFile multipartFile = FileUtils.getMulFile(file);

            //上传文件
            Response<String> response = iTencentSaasClient.uploadFile(multipartFile, "scrm", pathStr);
            if (EmptyUtils.isNotEmpty(response.getData())) {
                return response.getData();
            }
            log.error("导出失败 请求上传文件失败, msg:{}", response.getMsg());
        } catch (Exception e) {
            log.error("导出失败", e);
        }
        return "";
    }

    /**
     * 添加导出的策略
     *
     * @param excelDtoList 导出数据
     * @return 导出策略数据
     */
    public static Map<String, List<RowRangeUtil>> addMerStrategy(List<ClueExportResponse> excelDtoList) {
        Map<String, List<RowRangeUtil>> strategyMap = new HashMap<>();
        ClueExportResponse preExcelDto = null;
        for (int i = 0; i < excelDtoList.size(); i++) {
            ClueExportResponse currDto = excelDtoList.get(i);
            if (preExcelDto != null) {
                //从第二行开始判断是否需要合并
                if (currDto.getClueId().equals(preExcelDto.getClueId())) {
                    for (int col = 0; col < clueExportMergeSize; col++) {
                        fillStrategyMap(strategyMap, String.valueOf(col), i);
                    }
                }
            }
            preExcelDto = currDto;
        }
        return strategyMap;
    }

    /**
     * 新增或修改合并策略map(EasyExcel)
     *
     * @param strategyMap 参数
     * @param key         参数
     * @param index       参数
     */
    private static void fillStrategyMap(Map<String, List<RowRangeUtil>> strategyMap, String key, int index) {
        List<RowRangeUtil> rowRangeDtoList = strategyMap.get(key) == null ? Lists.newArrayList() : strategyMap.get(key);
        boolean flag = false;
        for (RowRangeUtil dto : rowRangeDtoList) {
            //分段list中是否有end索引是上一行索引的，如果有，则索引+1
            if (dto.getEnd() == index) {
                dto.setEnd(index + 1);
                flag = true;
            }
        }
        //如果没有，则新增分段
        if (!flag) {
            rowRangeDtoList.add(new RowRangeUtil(index, index + 1));
        }
        strategyMap.put(key, rowRangeDtoList);
    }

    /**
     * 获取线索转化为导出线索格式
     *
     * @param clueList 线索列表
     * @return 线索导出列表数据
     */
    private List<ClueExportResponse> getClueCustomerCollectExportResponses(List<ClueCustomerCollectResponse> clueList) {
        //获取跟进历史信息
        Map<Long, List<CustomerFollowRecordResponse>> recordMap = getRecordListMap(clueList);

        List<ClueExportResponse> responseList = Lists.newArrayList();
        clueList.forEach(clue -> {
            //当跟进历史存在多条时，线索导出为多条，后续合并单元格
            if (EmptyUtils.isNotEmpty(recordMap) && recordMap.containsKey(clue.getClueId())
                    && EmptyUtils.isNotEmpty(recordMap.get(clue.getClueId()))) {
                List<CustomerFollowRecordResponse> recordList = recordMap.get(clue.getClueId());
                recordList.forEach(record -> {
                    ClueExportResponse exportResponse = transClueExportResponse(clue);
                    exportResponse.setOperateTime(record.getOperateTime());
                    if (EmptyUtils.isNotEmpty(record.getSecondStatus())) {
                        exportResponse.setSecondStatus(record.getSecondStatus());
                    }
                    exportResponse.setFollowDetail(record.getFollowDetail());
                    exportResponse.setFollowEmpName(record.getFollowEmpName());
                    responseList.add(exportResponse);
                });
                return;
            }
            ClueExportResponse exportResponse = transClueExportResponse(clue);
            responseList.add(exportResponse);
        });
        return responseList;
    }

    /**
     * 获取线索列表数据的跟进历史记录
     *
     * @param clueList 线索列表
     * @return 线索id与线索跟进记录的map
     */
    private Map<Long, List<CustomerFollowRecordResponse>> getRecordListMap(List<ClueCustomerCollectResponse> clueList) {
        List<Long> clueIds = clueList.stream().map(ClueCustomerCollectResponse::getClueId).filter(EmptyUtils::isNotEmpty).collect(Collectors.toList());
        Map<Long, List<CustomerFollowRecordResponse>> recordMap = null;
        if (EmptyUtils.isNotEmpty(clueIds)) {
            QueryCustomerFollowRecordRequest queryRequest = new QueryCustomerFollowRecordRequest();
            queryRequest.setClueIds(clueIds);
            queryRequest.setStatus(FollowRecordStatusEnum.FOLLOW_UP.getCode());
            List<CustomerFollowRecordResponse> recordList = customerFollowRecordService.getListByParam(queryRequest);
            if (EmptyUtils.isNotEmpty(recordList)) {
                recordMap = recordList.stream().collect(Collectors.groupingBy(CustomerFollowRecordResponse::getClueId));
            }
        }
        return recordMap;
    }

    /**
     * 转化为导出excel
     *
     * @param clue 线索信息
     * @return 导出的线索信息
     */
    private ClueExportResponse transClueExportResponse(ClueCustomerCollectResponse clue) {
        ClueExportResponse exportResponse = BeanUtil.copy(clue, ClueExportResponse.class);
        if (EmptyUtils.isNotEmpty(clue.getFirendStaus())) {
            exportResponse.setFriendStatus(clue.getFirendStaus());
        } else {
            exportResponse.setFriendStatus(FriendStatusEnum.FRIEND_UNBOUND.getCode());
        }
        return exportResponse;
    }

    /**
     * 获取所有线索信息
     *
     * @param request 参数
     * @return 所有线索信息
     */
    private List<ClueCustomerCollectResponse> getClueCustomerCollectResponses(PageRequest<QueryClueCustomerCollectAllRequest> request) {
        int pageNum = 1;
        int pagSize = 1000;
        request.setPageNum(pageNum);
        request.setPageSize(pagSize);
        PageResponse<ClueCustomerCollectResponse> pageResponse = this.getManagePageListByParam(request);
        if (EmptyUtils.isEmpty(pageResponse) || EmptyUtils.isEmpty(pageResponse.getDataList())) {
            return null;
        }
        List<ClueCustomerCollectResponse> clueList = pageResponse.getDataList();
        int total = pageResponse.getPage().getTotalCount().intValue();
        while (total > (pageNum * pagSize)) {
            pageNum++;
            PageResponse<ClueCustomerCollectResponse> responses = this.getManagePageListByParam(request);
            if (EmptyUtils.isNotEmpty(responses) && EmptyUtils.isNotEmpty(responses.getDataList())) {
                clueList.addAll(responses.getDataList());
            }
        }
        if (EmptyUtils.isEmpty(clueList)) {
            return Lists.newArrayList();
        }
        return clueList;
    }

    @Override
    public PageResponse<ClueCustomerCollectResponse> getManagePageListByParam(PageRequest<QueryClueCustomerCollectAllRequest> request) {
        ValidateUtils.checkObjNull(request, "参数不可以为null");

        PageResponse<ClueCustomerCollectResponse> collectResponse = new PageResponse<>();
        collectResponse.converPageResponse(new PageResponse(), new Page(), request);

        try {


            QueryClueCustomerCollectAllRequest queryRequest = request.getParamData();

            //线索来源查询-1、线索来源获取客户主键ID 2、根据总部客户ID与经销商客户ID获取所有线索ID
            if (EmptyUtils.isNotEmpty(queryRequest.getSourceThirdList())) {
                List<Long> clueIds = findClueIdsBySourceThirdList(queryRequest);
                if (EmptyUtils.isEmpty(clueIds)) {
                    return collectResponse;
                }
                queryRequest.setClueIds(clueIds);
            }

            //线索来源渠道和活动
            List<Map<String, Object>> channelActivityList = queryRequest.getChannelActivityList();
            if (CollectionUtils.isNotEmpty(channelActivityList)) {
                Set<String> resultActivityList = Sets.newHashSet();
                channelActivityList.stream().forEach(channelActivityMap -> {
                    ChannelActivityRequest channelActivityRequest = JSON.parseObject(JSON.toJSONString(channelActivityMap), ChannelActivityRequest.class);
                    String channelCode = channelActivityRequest.getChannelCode();
                    List<String> activityCodes = channelActivityRequest.getActivityCodes();

                    //如果活动不为空，则增加活动code
                    if (CollectionUtils.isNotEmpty(activityCodes)) {
                        resultActivityList.addAll(activityCodes);
                    } else {
                        //根据渠道查询所有活动
                        List<DictionariesResponse> responseList = tenantManager.getListByParentCode(channelCode);
                        if (CollectionUtils.isNotEmpty(responseList)) {
                            resultActivityList.addAll(responseList.stream().map(item -> item.getCode()).collect(Collectors.toSet()));
                        }
                    }
                });

                List<Long> clueIds = findClueIdsByActivityList(resultActivityList);
                if (EmptyUtils.isEmpty(clueIds)) {
                    return collectResponse;
                }
                queryRequest.setClueIds(clueIds);
            }

            //车系数据查询关联线索信息
            if (EmptyUtils.isNotEmpty(queryRequest) && EmptyUtils.isNotEmpty(queryRequest.getSeriesIds())) {
                ClueIntentionVehicle queryVeh = new ClueIntentionVehicle();
                queryVeh.setSeriesIds(queryRequest.getSeriesIds());
                queryVeh.setDeleted(DeleteEnum.INIT.getFlag());
                queryVeh.setClueIds(queryRequest.getClueIds());
                List<ClueIntentionVehicle> clueIntentionVehicles = clueIntentionVehicleService.getListByParam(queryVeh);
                if (EmptyUtils.isEmpty(clueIntentionVehicles)) {
                    return collectResponse;
                }
                List<Long> clueIds = clueIntentionVehicles.stream().map(ClueIntentionVehicle::getClueId).distinct().collect(Collectors.toList());
                queryRequest.setClueIds(clueIds);
            }

            //区域经销商
            List<Map<String, Object>> sectorDealerList = queryRequest.getSectorDealerList();
            if (CollectionUtils.isNotEmpty(sectorDealerList)) {
                Set<String> resultDealerIds = Sets.newHashSet();
                sectorDealerList.stream().forEach(sectorDealerMap -> {
                    SectorDealerRequest sectorDealerRequest = JSON.parseObject(JSON.toJSONString(sectorDealerMap), SectorDealerRequest.class);
                    Long sectorId = sectorDealerRequest.getSectorId();
                    List<String> dealerIds = sectorDealerRequest.getDealerIds();

                    //如果经销商集合不为空，则以经销商集合为准
                    if (CollectionUtils.isNotEmpty(dealerIds)) {
                        resultDealerIds.addAll(dealerIds);
                    } else {
                        //根据区域查询经销商
                        String tenantId = SearchLocalHeader.getHeader(SCRMRequestHeaderEnum.HEADER_TENANTID.getCode());
                        String corpId = SearchLocalHeader.getHeader(SCRMRequestHeaderEnum.HEADER_CORP_ACCOUNTID.getCode());
                        QueryDealerRequest queryDealerRequest = new QueryDealerRequest();
                        queryDealerRequest.setSectorId(sectorId.toString());
                        Response<List<DealerResponse>> dealerListByParamResponse = mdQueryClient.getDealerListByParam(queryDealerRequest, tenantId, corpId);
                        if (ResponseUtil.isSuccess(dealerListByParamResponse)) {
                            List<DealerResponse> data = dealerListByParamResponse.getData();

                            if (CollectionUtils.isNotEmpty(data)) {
                                resultDealerIds.addAll(data.stream().map(d -> String.valueOf(d.getId())).collect(Collectors.toSet()));
                            }
                        }
                    }
                });
                if (CollectionUtils.isEmpty(resultDealerIds)) {
                    return collectResponse;
                } else {
                    queryRequest.setDealerIds(Lists.newArrayList(resultDealerIds));
                }
            }

//        //经销商客户信息
//        if (EmptyUtils.isNotEmpty(queryRequest) && EmptyUtils.isNotEmpty(queryRequest.getDealerName())) {
//            QueryDealerRequest dealerQuery = new QueryDealerRequest();
//            dealerQuery.setName(request.getParamData().getDealerName());
//            dealerQuery.setDeleted(DeleteEnum.INIT.getFlag());
//            String tenantId = SearchLocalHeader.getHeader(SCRMRequestHeaderEnum.HEADER_TENANTID.getCode());
//            String corpId = SearchLocalHeader.getHeader(SCRMRequestHeaderEnum.HEADER_CORP_ACCOUNTID.getCode());
//            Response<List<DealerResponse>> dealerResponses = mdQueryClient.getDealerListByParam(dealerQuery, tenantId, corpId);
//            if (EmptyUtils.isEmpty(dealerResponses) || EmptyUtils.isEmpty(dealerResponses.getData())) {
//                return collectResponse;
//            }
//            List<String> dealerIds = dealerResponses.getData().stream().filter(EmptyUtils::isNotEmpty).map(de -> de.getId().toString()).collect(Collectors.toList());
//            queryRequest.setDealerIds(dealerIds);
//        }

            PageResponse<ClueCustomerCollect> pageResponse = clueCustomerCollectService.getPageByParamAll(request);
            log.info("查询线索入参={},list={}",JSON.toJSONString(request),JSON.toJSONString(pageResponse));
            if (EmptyUtils.isEmpty(pageResponse) || EmptyUtils.isEmpty(pageResponse.getDataList())) {
                return ClueCustomerCollectAssembler.transformPOToResponseVoPage(pageResponse, ClueCustomerCollectResponse.class);
            }
            collectResponse = ClueCustomerCollectAssembler.transformPOToResponseVoPage(pageResponse, ClueCustomerCollectResponse.class);
            List<ClueCustomerCollect> collects = pageResponse.getDataList();
            //获取意向信息
            Map<Long, List<ClueIntentionVehicle>> clueVehMap = getClueIntentionVehListMap(collects);

            //总部客户信息
            Map<Long, CustomerResponse> oemCustomerMap = getOemCustomerMap(collects);

            //经销商客户信息
            Map<Long, CustomerResponse> dealerCustomerMap = getDealerCustomerMap(collects);

            Map<String, String> dicMap = tenantManager.getDicMapGroupByCode(new QueryDictionariesRequest());
            //获取经销商信息
            Map<Long, DealerResponse> dealerMap = getDealerResponseMap(collects);

            List<ClueCustomerCollectResponse> collectResponses = BeanUtil.copyByList(collects, ClueCustomerCollectResponse.class);
            collectResponses.forEach(cr -> {
                //填充车系车型信息
                if (EmptyUtils.isNotEmpty(clueVehMap) && clueVehMap.containsKey(cr.getClueId())
                        && EmptyUtils.isNotEmpty(clueVehMap.get(cr.getClueId()))) {
                    List<ClueIntentionVehicleResponse> vehicleResponses = BeanUtil.copyByList(clueVehMap.get(cr.getClueId()), ClueIntentionVehicleResponse.class);
                    cr.setVehicleList(vehicleResponses);
                    fillResponseVehInfo(cr, vehicleResponses);
                }

                //填充经销商信息
                Long dealerId = CommonUtil.getLongByObj(cr.getDealerId());
                if (EmptyUtils.isNotEmpty(dealerMap) && EmptyUtils.isNotEmpty(dealerId)
                        && dealerMap.containsKey(dealerId) && EmptyUtils.isNotEmpty(dealerMap.get(dealerId))) {
                    DealerResponse dealerResponse = dealerMap.get(dealerId);
                    cr.setDealerName(dealerResponse.getName());
                    cr.setSectorName(dealerResponse.getSectorName());
                }

                //填充经销商客户活动与渠道信息
                if (CustomerUtil.isDealer(cr.getDealerId())) {
                    fillChanelAndActivity(cr.getCusId(), dealerCustomerMap, dicMap, cr);
                } else {
                    //填充总部客户活动与渠道信息
                    fillChanelAndActivity(cr.getCusId(), oemCustomerMap, dicMap, cr);
                }
            });
            collectResponse.setDataList(collectResponses);
            return collectResponse;
        }catch (Exception e){
            e.printStackTrace();
        }
        return collectResponse;
    }

    private List<Long> findClueIdsByActivityList(Set<String> resultActivityList) {
        List<Clue> clues = Lists.newArrayList();
        QueryCustomerRequest customerRequest = new QueryCustomerRequest();
        customerRequest.setDeleted(DeleteEnum.INIT.getFlag());
        customerRequest.setSourceActivityList(new ArrayList<>(resultActivityList));
        List<CustomerResponse> oemCustomerResponses = oemCustomerService.getListByParam(customerRequest);
        if (EmptyUtils.isNotEmpty(oemCustomerResponses)) {
            List<Long> oemCusIds = oemCustomerResponses.stream().map(CustomerResponse::getId).collect(Collectors.toList());
            Clue clueRequest = new Clue();
            clueRequest.setCusIds(oemCusIds);
            clueRequest.setDeleted(DeleteEnum.INIT.getFlag());
            clueRequest.setCusType(CustomerTypeEnum.CUSTOMER_TYPE_OEM.getCode());
            List<Clue> oemClues = clueService.getListByParam(clueRequest);
            if (EmptyUtils.isNotEmpty(oemClues)) {
                clues.addAll(oemClues);
            }
        }
        List<CustomerResponse> dealerCustomerResponses = dealerCustomerService.getListByParam(customerRequest);
        if (EmptyUtils.isNotEmpty(dealerCustomerResponses)) {
            List<Long> dealerCusIds = dealerCustomerResponses.stream().map(CustomerResponse::getId).collect(Collectors.toList());
            Clue clueRequest = new Clue();
            clueRequest.setCusIds(dealerCusIds);
            clueRequest.setDeleted(DeleteEnum.INIT.getFlag());
            clueRequest.setCusType(CustomerTypeEnum.CUSTOMER_TYPE_DEALER.getCode());
            List<Clue> dealerClues = clueService.getListByParam(clueRequest);
            if (EmptyUtils.isNotEmpty(dealerClues)) {
                clues.addAll(dealerClues);
            }
        }
        if (EmptyUtils.isEmpty(clues)) {
            return null;
        }
        return clues.stream().map(Clue::getId).collect(Collectors.toList());
    }

    private List<Long> findClueIdsBySourceThirdList(QueryClueCustomerCollectAllRequest queryRequest) {
        List<Clue> clues = Lists.newArrayList();
        //1、线索来源获取客户主键ID
        QueryCustomerRequest customerRequest = new QueryCustomerRequest();
        customerRequest.setDeleted(DeleteEnum.INIT.getFlag());
        customerRequest.setSourceThirdList(queryRequest.getSourceThirdList());
        List<CustomerResponse> oemCustomerResponses = oemCustomerService.getListByParam(customerRequest);
        if (EmptyUtils.isNotEmpty(oemCustomerResponses)) {
            List<Long> oemCusIds = oemCustomerResponses.stream().map(CustomerResponse::getId).collect(Collectors.toList());
            Clue clueRequest = new Clue();
            clueRequest.setCusIds(oemCusIds);
            clueRequest.setDeleted(DeleteEnum.INIT.getFlag());
            clueRequest.setCusType(CustomerTypeEnum.CUSTOMER_TYPE_OEM.getCode());
            List<Clue> oemClues = clueService.getListByParam(clueRequest);
            if (EmptyUtils.isNotEmpty(oemClues)) {
                clues.addAll(oemClues);
            }
        }
        List<CustomerResponse> dealerCustomerResponses = dealerCustomerService.getListByParam(customerRequest);
        if (EmptyUtils.isNotEmpty(dealerCustomerResponses)) {
            List<Long> dealerCusIds = dealerCustomerResponses.stream().map(CustomerResponse::getId).collect(Collectors.toList());
            Clue clueRequest = new Clue();
            clueRequest.setCusIds(dealerCusIds);
            clueRequest.setDeleted(DeleteEnum.INIT.getFlag());
            clueRequest.setCusType(CustomerTypeEnum.CUSTOMER_TYPE_DEALER.getCode());
            List<Clue> dealerClues = clueService.getListByParam(clueRequest);
            if (EmptyUtils.isNotEmpty(dealerClues)) {
                clues.addAll(dealerClues);
            }
        }
        if (EmptyUtils.isEmpty(clues)) {
            return null;
        }
        return clues.stream().map(Clue::getId).collect(Collectors.toList());
    }

    private void fillChanelAndActivity(Long cusId, Map<Long, CustomerResponse> customerMap, Map<String, String> dicMap, ClueCustomerCollectResponse response) {
        if (!CustomerUtil.checkCusId(cusId) || EmptyUtils.isEmpty(customerMap) || !customerMap.containsKey(cusId) || EmptyUtils.isEmpty(customerMap.get(cusId))) {
            return;
        }
        CustomerResponse customer = customerMap.get(cusId);
        if (EmptyUtils.isNotEmpty(dicMap) && EmptyUtils.isNotEmpty(customer.getSourceThird())
                && EmptyUtils.isNotEmpty(dicMap.get(customer.getSourceThird()))) {
            response.setSourceThird(dicMap.get(customer.getSourceThird()));
        }
        if (EmptyUtils.isNotEmpty(dicMap) && EmptyUtils.isNotEmpty(customer.getSourceActivityId())
                && EmptyUtils.isNotEmpty(dicMap.get(customer.getSourceActivityId()))) {
            response.setSourceActivityId(dicMap.get(customer.getSourceActivityId()));
        }
    }

    private Map<Long, List<ClueIntentionVehicle>> getClueIntentionVehListMap(List<ClueCustomerCollect> collects) {
        List<Long> clueIds = collects.stream().map(ClueCustomerCollect::getClueId)
                .filter(EmptyUtils::isNotEmpty).distinct().collect(Collectors.toList());
        if (EmptyUtils.isEmpty(clueIds)) {
            return null;
        }
        ClueIntentionVehicle queryVeh = new ClueIntentionVehicle();
        queryVeh.setClueIds(clueIds);
        queryVeh.setDeleted(DeleteEnum.INIT.getFlag());
        List<ClueIntentionVehicle> vehicleList = clueIntentionVehicleService.getListByParam(queryVeh);
        if (EmptyUtils.isEmpty(vehicleList)) {
            return null;
        }
        return vehicleList.stream().collect(Collectors.groupingBy(ClueIntentionVehicle::getClueId));
    }

    private Map<Long, DealerResponse> getDealerResponseMap(List<ClueCustomerCollect> collects) {
        List<Long> dealerIds = collects.stream().filter(cl -> EmptyUtils.isNotEmpty(cl.getDealerId()) && !"0".equals(cl.getDealerId()))
                .map(clue -> Long.parseLong(clue.getDealerId())).distinct().collect(Collectors.toList());
        if (EmptyUtils.isEmpty(dealerIds)) {
            return null;
        }
        QueryDealerRequest queryDealerRequest = new QueryDealerRequest();
        queryDealerRequest.setIds(dealerIds);
        queryDealerRequest.setDeleted(DeleteEnum.INIT.getFlag());
        String tenantId = SearchLocalHeader.getHeader(SCRMRequestHeaderEnum.HEADER_TENANTID.getCode());
        String corpId = SearchLocalHeader.getHeader(SCRMRequestHeaderEnum.HEADER_CORP_ACCOUNTID.getCode());
        Response<List<DealerResponse>> dealerResponse = mdQueryClient.getDealerListByParam(queryDealerRequest, tenantId, corpId);
        if (EmptyUtils.isEmpty(dealerResponse) || EmptyUtils.isEmpty(dealerResponse.getData())) {
            return null;
        }
        List<DealerResponse> dealerList = dealerResponse.getData();
        return dealerList.stream().collect(Collectors.toMap(DealerResponse::getId, de -> de, (oldValue, newValue) -> newValue));
    }

    private Map<Long, CustomerResponse> getDealerCustomerMap(List<ClueCustomerCollect> clueList) {
        List<Long> dealerCusIds = clueList.stream().filter(cl -> EmptyUtils.isNotEmpty(cl.getCusId())
                        && EmptyUtils.isNotEmpty(cl.getDealerId()) && !"0".equals(cl.getDealerId()))
                .map(ClueCustomerCollect::getCusId).distinct().collect(Collectors.toList());
        if (EmptyUtils.isEmpty(dealerCusIds)) {
            return null;
        }
        QueryCustomerRequest dealerQuery = new QueryCustomerRequest();
        dealerQuery.setIds(dealerCusIds);
        dealerQuery.setDeleted(DeleteEnum.INIT.getFlag());
        dealerQuery.setCusType(CustomerTypeEnum.CUSTOMER_TYPE_DEALER.getCode());
        return this.getCustomerMapByCusType(dealerQuery);
    }

    private Map<Long, CustomerResponse> getOemCustomerMap(List<ClueCustomerCollect> clueList) {
        List<Long> oemCusIds = clueList.stream().filter(cl -> EmptyUtils.isNotEmpty(cl.getCusId())
                        && (EmptyUtils.isEmpty(cl.getDealerId()) || "0".equals(cl.getDealerId())))
                .map(ClueCustomerCollect::getCusId).distinct().collect(Collectors.toList());
        if (EmptyUtils.isEmpty(oemCusIds)) {
            return null;
        }
        QueryCustomerRequest dealerQuery = new QueryCustomerRequest();
        dealerQuery.setIds(oemCusIds);
        dealerQuery.setDeleted(DeleteEnum.INIT.getFlag());
        dealerQuery.setCusType(CustomerTypeEnum.CUSTOMER_TYPE_OEM.getCode());
        return this.getCustomerMapByCusType(dealerQuery);
    }

    private void fillResponseVehInfo(ClueCustomerCollectResponse clue, List<ClueIntentionVehicleResponse> vehicleList) {
        if (EmptyUtils.isEmpty(vehicleList)) {
            return;
        }
        List<String> vehInfoList = Lists.newArrayList();
        vehicleList.forEach(veh -> {
            String vehInfo="";
            if(StringUtils.isNotEmpty(veh.getSeriesName())&&StringUtils.isNotEmpty(veh.getModelName())){
                vehInfo = String.format("%s-%s", veh.getSeriesName(), veh.getModelName());
            }else {
                vehInfo =StringUtils.isNotEmpty(veh.getSeriesName())?veh.getSeriesName():veh.getModelName();
            }
            vehInfoList.add(vehInfo);
        });
        if (EmptyUtils.isNotEmpty(vehInfoList)) {
            clue.setVehInfo(StringUtils.join(vehInfoList, ";"));
        }
    }
}
